//
//  HJPullDownRefreshControl.swift
//  Micro-blog Sina
//
//  Created by admin on 16/3/28.
//  Copyright © 2016年 admin. All rights reserved.
//

import UIKit

// Defind refresh status
enum HJPullDownRefreshStatus: Int {
    case Normal
    case PullToRefresh
    case Refreshing
}

private let HJRefreshControlHeight: CGFloat = 60

class HJPullDownRefreshControl: UIView {
    var pullToRefreshHandler: (() -> ())?
    // MARK: - Attribute
    private weak var scrollView: UIScrollView!
    private var previousStatus: HJPullDownRefreshStatus = .Normal
    private var currentStatus: HJPullDownRefreshStatus = .Normal {
        didSet {
            switch currentStatus {
            case .Normal:
                arrowView.hidden = false
                rotationView.hidden = true
                messageLabel.text = "下拉刷新"
                UIView.animateWithDuration(HJDefaultDuration, animations: { () -> Void in
                    self.arrowView.transform = CGAffineTransformIdentity
                })
                if previousStatus == .Refreshing {
                    UIView.animateWithDuration(HJDefaultDuration, animations: { () -> Void in
                        self.scrollView.contentInset.top -= HJRefreshControlHeight
                    })
                }
                
            case .PullToRefresh:
                messageLabel.text = "释放刷新"
                UIView.animateWithDuration(HJDefaultDuration, animations: { () -> Void in
                    self.arrowView.transform = CGAffineTransformMakeRotation(CGFloat(M_PI - 0.001))
                })
            case .Refreshing:
                arrowView.hidden = true
                rotationView.hidden = false
                messageLabel.text = "正在刷新..."
                let rotation = CABasicAnimation(keyPath: "transform.rotation")
                rotation.toValue = M_PI * 2
                rotation.duration = 0.5
                rotation.repeatCount = MAXFLOAT
                rotationView.layer.addAnimation(rotation, forKey: "rotation")
                
                UIView.animateWithDuration(HJDefaultDuration, animations: { () -> Void in
                    self.scrollView.contentInset.top += HJRefreshControlHeight
                    }, completion: { (_) -> Void in
                        self.pullToRefreshHandler?()
                })
            }
            // Record the currentStatus
            previousStatus = currentStatus
        }
        
    }
    func startRefreshing() {
        currentStatus = .Refreshing
    }
    
    func stopRefreshing() {
        currentStatus = .Normal
    }
    
    required init?(coder aDecoder: NSCoder) {
        fatalError("init(coder:) has not been implemented")
    }
    override init(frame: CGRect) {
        let newFrame = CGRect(x: 0, y: -HJRefreshControlHeight, width: UIScreen.width, height: HJRefreshControlHeight)
        super.init(frame: newFrame)
        backgroundColor = UIColor.clearColor()
        prepareUI()
    }
    
    private func prepareUI() {
        addSubview(arrowView)
        addSubview(rotationView)
        addSubview(messageLabel)
        
        rotationView.hidden = true
        
        arrowView.translatesAutoresizingMaskIntoConstraints = false
        rotationView.translatesAutoresizingMaskIntoConstraints = false
        messageLabel.translatesAutoresizingMaskIntoConstraints = false
        
        addConstraint(NSLayoutConstraint(item: arrowView, attribute: NSLayoutAttribute.CenterX, relatedBy: NSLayoutRelation.Equal, toItem: self, attribute: NSLayoutAttribute.CenterX, multiplier: 1, constant: -30))
        addConstraint(NSLayoutConstraint(item: arrowView, attribute: NSLayoutAttribute.CenterY, relatedBy: NSLayoutRelation.Equal, toItem: self, attribute: NSLayoutAttribute.CenterY, multiplier: 1, constant: 0))
        
        addConstraint(NSLayoutConstraint(item: rotationView, attribute: NSLayoutAttribute.CenterX, relatedBy: NSLayoutRelation.Equal, toItem: arrowView, attribute: NSLayoutAttribute.CenterX, multiplier: 1, constant: 0))
        addConstraint(NSLayoutConstraint(item: rotationView, attribute: NSLayoutAttribute.CenterY, relatedBy: NSLayoutRelation.Equal, toItem: arrowView, attribute: NSLayoutAttribute.CenterY, multiplier: 1, constant: 0))
        
        addConstraint(NSLayoutConstraint(item: messageLabel, attribute: NSLayoutAttribute.Leading, relatedBy: NSLayoutRelation.Equal, toItem: arrowView, attribute: NSLayoutAttribute.Trailing, multiplier: 1, constant: 10))
        addConstraint(NSLayoutConstraint(item: messageLabel, attribute: NSLayoutAttribute.CenterY, relatedBy: NSLayoutRelation.Equal, toItem: arrowView, attribute: NSLayoutAttribute.CenterY, multiplier: 1, constant: 0))
    }

    override func willMoveToSuperview(newSuperview: UIView?) {
        super.willMoveToSuperview(newSuperview)
        if let scrollView = newSuperview as? UIScrollView {
            self.scrollView = scrollView
            // Using KVO monitor
            scrollView.addObserver(self, forKeyPath: "contentOffset", options: [NSKeyValueObservingOptions.New, NSKeyValueObservingOptions.Old], context: nil)
        }
    }
    // KVO CallBack the mothed when keyPath changed 
    override func observeValueForKeyPath(keyPath: String?, ofObject object: AnyObject?, change: [String : AnyObject]?, context: UnsafeMutablePointer<Void>) {
        if scrollView.dragging {
            if currentStatus == .PullToRefresh && scrollView.contentOffset.y > -scrollView.contentInset.top - HJRefreshControlHeight {
                HJPrint(msg: "切换到.Normal状态")
                currentStatus = .Normal
            }else if currentStatus == .Normal && scrollView.contentOffset.y <= -scrollView.contentInset.top - HJRefreshControlHeight {
                HJPrint(msg: "切换到.PullToRefresh状态")
                currentStatus = .PullToRefresh
            }
        }else if currentStatus == .PullToRefresh {
            HJPrint(msg: "切换到.Refreshing状态")
            currentStatus = .Refreshing
            
        }
    }
    
    
    // Remove the KVO monitor
    deinit {
        superview?.removeObserver(self, forKeyPath: "contentOffset")
    }
    
    // MARK: - Lazy load 
    private lazy var arrowView: UIImageView = UIImageView(image: UIImage(named: "tableview_pull_refresh"))
    private lazy var rotationView: UIImageView = UIImageView(image: UIImage(named: "tableview_loading"))
    private lazy var messageLabel: UILabel = {
        let label = UILabel()
        label.textColor = UIColor.darkGrayColor()
        label.font = UIFont.systemFontOfSize(15)
        label.text = "下拉刷新"
        return label
    }()
}

private var pullDownRefreshControlKey = "HJPullDownRefreshControlKey"
extension UIScrollView {
    private var pullDownRefreshControl: HJPullDownRefreshControl {
        get {
            if let refreshControl = objc_getAssociatedObject(self, &pullDownRefreshControlKey) as? HJPullDownRefreshControl {
                return refreshControl
            }else {
                let refreshControl = HJPullDownRefreshControl()
                self.addSubview(refreshControl)
                self.pullDownRefreshControl = refreshControl
                return refreshControl
            }
        }
        set {
            objc_setAssociatedObject(self, &pullDownRefreshControlKey, newValue, objc_AssociationPolicy.OBJC_ASSOCIATION_RETAIN_NONATOMIC)
        }
    }
    
    // MARK: - 添加两个对外公开的方法
    func addPullDownRefreshHandler(handler: () -> ()) {
        pullDownRefreshControl.pullToRefreshHandler = handler
    }
    func startRefreshing() {
        pullDownRefreshControl.startRefreshing()
    }
    func stopRefreshing() {
        pullDownRefreshControl.stopRefreshing()
    }
    
}


